package solitaire.presentation;

import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DragSourceMotionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;

import solitaire.InterfacesControle.ICTasDeCartes;
import solitaire.InterfacesPresentation.IPCarte;
import solitaire.InterfacesPresentation.IPTasDeCartes;
import solitaire.application.Carte;
import solitaire.controle.CTasDeCartes;
import solitaire.controle.CUsine;

public class DnDListener implements DragSourceListener,DragGestureListener,DragSourceMotionListener{
	private CUsine usine;
	private static DnDListener instance;
	private static JFrame ihm;
	private IPTasDeCartes tasSourceDnD;

	public DnDListener(CUsine usine) { 
		this.usine=usine;
		instance=this;
	}

	public static DnDListener getInstance() {
		return instance;
	}

	@Override
	public void dragMouseMoved(DragSourceDragEvent dsde) {
		System.out.println("drag mouse moved event");

	}

	@Override
	public void dragGestureRecognized(DragGestureEvent dge) {
		IPCarte ipcarte=(IPCarte) dge.getComponent();
		IPTasDeCartes tas=(IPTasDeCartes) ipcarte.getJPanel().getParent();
		tasSourceDnD=tas;
		
		//Tas temporaire
		ICTasDeCartes tasTemp=(CTasDeCartes) usine.newTasDeCartes("tasTemp", usine);

		//les operation d'empiler/depiler doivent se faire apres l'appel a la fonctio debutDnD, sinon
		//exceptions sur mac et linux.
		if(ipcarte.debutDnD(dge,tasTemp)){
			//dans le cas du sabot (pas de déplacement de pile)
			if(tas.getControleur().getNom()=="Sabot"){
				tasTemp.empiler(ipcarte.getControleur().getAbstraction());

			}
			else{
				List<Carte> list=new ArrayList<Carte>();
				while(tas.getControleur().getICCarteSommet()!=ipcarte.getControleur()){
					list.add(tas.getControleur().getICCarteSommet().getAbstraction());
					tas.getControleur().depiler();
				}
				list.add(tas.getControleur().getICCarteSommet().getAbstraction());
				tas.getControleur().depiler();
				
				//necessaire afin d'empiler les cartes dans le bon ordre
				for(int i=list.size();i>0;i--){
					tasTemp.empiler(list.get(i-1));
				}


			}
		}

		

	}

	@Override
	public void dragDropEnd(DragSourceDropEvent dsde) {
		if(!dsde.getDropSuccess()){
			try {
				ICTasDeCartes tas=(ICTasDeCartes) dsde.getDragSourceContext().getTransferable().getTransferData(dsde.getDragSourceContext().getTransferable().getTransferDataFlavors()[0]);
				//re-empiler les cartes ds le bon ordre.
				List<Carte> list=new ArrayList<Carte>();
				while(tas.getNombre()!=0){
					list.add((Carte) tas.getICCarteSommet());
					tas.depiler();
				}
				
				//necessaire afin d'empiler les cartes dans le bon ordre
				for(int i=list.size();i>0;i--){
					tasSourceDnD.getControleur().empiler(list.get(i-1));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		//retourne des cartes di le tas visible d'une colonne est vide suite a un DnD
		else{
			if(tasSourceDnD.getClass()==PTasDeCartesAlternees.class){
				PColonne colonne=(PColonne) tasSourceDnD.getJComponent().getParent();
				colonne.getControleur().retournerCCarte();
			}
			
		}
		ihm.invalidate();
		ihm.validate();
		ihm.repaint();
	}

	@Override
	public void dragEnter(DragSourceDragEvent dsde) {
		// TODO Auto-generated method stub

	}

	@Override
	public void dragExit(DragSourceEvent dse) {
		// TODO Auto-generated method stub

	}

	@Override
	public void dragOver(DragSourceDragEvent dsde) {
		// TODO Auto-generated method stub

	}

	@Override
	public void dropActionChanged(DragSourceDragEvent dsde) {
		// TODO Auto-generated method stub

	}

	public static void setIHM(PSolitaire presentation) {
		ihm=presentation;
		
	}

}
